/*------------------------------------------------*/
/* Touch sensor test program R0.1a (C)ChaN, 2007  */
/*                      Mod DZ   2010             */
/*                      reverse outout Hi <-> Low */
/* ATtiny2313 Internal osc 8MHz                   */
/*------------------------------------------------*/

#include <avr/io.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include "suart.h"
#include "xitoa.h"
#include "cs.h"

#define SYSCLK	8000000UL


/*------------------------------------------------*/
/* Global variables                               */

char line[16];	/* Console input buffer */



/*------------------------------------------------*/


static
void get_line (char *buff, int len)
{
	char c;
	int idx = 0;


	for (;;) {
		c = rcvr();
		if (c == '\r') break;
		if ((c == '\b') && idx) {
			idx--; xputc(c);
		}
		if (((unsigned char)c >= ' ') && (idx < len - 1)) {
				buff[idx++] = c; xputc(c);
		}
	}
	buff[idx] = 0;
	xputc(c);
	xputc('\n');
}



void get_sens (int *res, int chs)
{
	int ch, loop;

	/* Clear count accumlator */
	for (ch = 0; ch < chs; ch++) res[ch] = 0;

	/* Capture and accumlate integration time for 1/60 second */
	OCR0A = 8000000UL / 1024 / 60;
	TCNT0 = 0;
	TIFR = _BV(OCF0A);
	TCCR0B = 0b101;
	loop = 0;
	do {
		for (ch = 0; ch < chs; ch++) res[ch] += touch(ch);
		loop++;
	} while ((TIFR & _BV(OCF0A)) == 0);
	TCCR0B = 0;

	/* Mean calculation */
	for (ch = 0; ch < chs; ch++) res[ch] /= loop;
}



/*------------------------------------------------*/
/* Online Monitor                                 */

int main (void)
{
	char *cp;
	int n, c, ref[8], val[8];


	PORTB = 0b10111111;	/* Initialize I/O port */
	DDRB  = 0b01000000;
	PORTD = 0b1000000;
	DDRD =  0b0111111;
	PORTA = 0b100;
	DDRA  = 0b011;


	get_sens(ref, 8);	/* Get reference count for each channel */

	if (1) {	/* Standalone mode */
		/* Re-initialize I/O port as sens outputs */
		PORTB = 0b00000000;
		DDRB  = 0b11111111;
		for (;;) {
			get_sens(val, 8);
			for (c = 0; c < 8; c++) {
				n = val[c] - ref[c];
/*
				if (n < 3) PORTB &= ~(1 << (7 - c));
				if (n > 5) PORTB |= (1 << (7 - c));
*/
				if (n < 3) PORTB |= (1 << (7 - c));
				if (n > 5) PORTB &= ~(1 << (7 - c));
			}
		}
	}

	/* Interactive mode */
	xfunc_out = (void(*)(char))xmit;
	xputs(PSTR("\nTouch sensor test program\n"));

	for(;;) {
		xputc('>');						/* Prompt */
		get_line(line, sizeof(line));
		cp = line;

		switch (*cp++) {	/* Pick a header char (command) */
			case '\0' :		/* Blank line */
				break;

			case 's' :		/* Read sensor */
				xputs(PSTR(" ch0 ch1 ch2 ch3 ch4 ch5 ch6 ch7\n"));
				do {
					get_sens(val,8);
					for (c = 0; c < 8; c++) xitoa(val[c] - ref[c], -10, 4);
					xputc('\r');
				} while (bit_is_clear(PINB, 5));	/* repeart until a break detected */
				xputc('\n');
				break;

			default :		/* Unknown command */
				xputs(PSTR("\n???"));
		}
		
	}
}


